﻿using HDW_Migrate.Db.Entities;
using HDW_Migrate.Resources;

namespace HDW_Migrate.Extensions;

/// <summary>
/// ArchiveView扩展
/// </summary>
public static class ArchiveViewEx
{
    /// <summary>
    /// 将检查数据源解析为 ArchiveView 对象
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public static ArchiveUploadPara ParseArchiveView(this IntegratedData data)
    {
        var procedure = data.Procedures?.FirstOrDefault()?.Procedure;
        var archive = new ArchiveView
        {
            Id = data.Order.Id,
            ReportId = data.Report?.Id,
            ArchiveId = data.Order.Id.ToString(),
            HasReqAssist = data.Order.RegionAssist,
            ServerNode = data.Order.ServerNode,
            HospitalCode = data.Hospital?.Code,
            HospitalName = data.Hospital?.Name,
            LastUpdateTime = data.Order.LastUpdateDateTime,
            Patient = new PatientArchive
            {
                Name = data.Patient.Name,
                SpellName = data.Patient.SpellName,
                Gender = data.Patient.Gender,
                GlobalPatientId = data.Patient.GlobalPatientId,
                HisPatientId = data.Patient.HISPatientId,
                PatientIndex = data.Patient.PatientMasterIndex ?? (data.Patient.ServerNode + '_' + data.Patient.GlobalPatientId),
                DateOfBirth = data.Patient.DateOfBirth,
                Age = data.Order.Age,
                AgeUnit = data.Order.AgeUnit,
                IDCard = data.Patient.IDCard.ToDecryptContent(),
                Address = data.Patient.Address,
                Telephone = data.Patient.Telephone.ToDecryptContent(),
                SocietyNumber = data.Patient.SocietyNumber
            },
            Visit = new VisitArchive
            {
                IsVIP = data.Visit.IsVIP,
                ClinicalNumber = data.Visit.ClinicalNumber,
                InpatientNumber = data.Visit.InpatientNumber,
                PatientType = data.Visit.PatientType,
                Critical = data.Critical?.Name,
                EmergencyDegree = data.Critical?.Sort.ToString() ?? "1",
                BedNumber = data.Visit.BedNumber,
                RoomNumber = data.Visit.RoomNumber,
                ClinicalDiagnosis = data.Visit.ClinicalDiagnosis,
                AllergyHistory = data.Visit.AllergyHistory,
                VisitNumber = data.Visit.VisitNumber,
                Symptom = data.Visit.Symptom,
                Sign = data.Visit.Sign,
                LaboratoryReport = data.Visit.LaboratoryReport,
                OtherDiagnosis = data.Visit.OtherDiagnosis,
                DiseaseHistory = data.Visit.DiseaseHistory,
                PatientIdentity = data.Identity?.Name,
                ChargeType = data.ChargeType?.Name,
                InfectionResult = data.InfectionResult?.Name,
                HpTestResult = data.HpTestResult?.Name
            },
            Order = new OrderArchive
            {
                HisOrderCodes = [data.Order.HisOrderCode],
                HisRequestDate = data.Order.HisOrderRequestDate?.ToDateTime(),
                HisExamName = data.Order.HisExamName,
                RegisterTime = data.Order.RegisterTime,
                AccessionNumber = data.Order.AccessionNumber,
                DeviceCode = data.Device?.Code,
                DeviceName = data.Device?.Name,
                DeviceAETitle = data.Device?.AETitle,
                ExamRoom = data.Device?.ExamRoom,
                ExecDepartmentCode = data.ExecDepartment?.Code,
                ExecDepartmentName = data.ExecDepartment?.Name,
                ExecDoctorCode = data.ExecDoctor?.Code,
                ExecDoctorName = data.ExecDoctor?.Name,
                ModalityCode = data.Modality?.Code,
                ModalityName = data.Modality?.Name,
                CheckTypes = data.Procedures?.Select(a => a.CheckType?.Name).ToArray(),
                Procedures = data.Procedures?.Select(a => a.ToArchiveProcedure()).ToArray(),
                TotalFee = data.Order.TotalFee,
                Note = data.Order.Note,
                Suggestion = data.Order.Suggestion,
                ApplyDepartmentCode = data.ApplyDepartment?.Code,
                ApplyDepartmentName = data.ApplyDepartment?.Name,
                ApplyDoctorCode = data.ApplyDoctor?.Code,
                ApplyDoctorName = data.ApplyDoctor?.Name,
                CheckInTime = data.Order.ArriveTime,
                CheckInDoctorCode = data.CheckInDoctor?.Code,
                CheckInDoctorName = data.CheckInDoctor?.Name,
                ExamReadyConfirmed = data.Order.StudyDate.HasValue,
                ExamFinishConfirmed = data.Order.StudyDate.HasValue,
                FilmingRank = data.Report?.FilmingRank,
                QueueNumber = data.Order.QueueNumber + "",
                IsMatch = data.Order.IsMatch,
                IsFromRIS = false,
                PaperOrderLinks = null,       // todo
                Status = data.Order.Status
            },
            Report = data.Report == null ? null : new ReportArchive
            {
                SubmitTime = data.Report.SubmitDateTime,
                SubmitDoctorCode = data.SubmitDoctor?.Code,
                SubmitDoctorName = data.SubmitDoctor?.Name,
                ApproveTime = data.Report.ApproveDatetime,
                ApproveDoctorCode = data.ApproveDoctor?.Code,
                ApproveDoctorName = data.ApproveDoctor?.Name,
                Findings = data.Report.Findings,
                Impression = data.Report.Impression,
                TechParams = data.Report.TechParams,
                PositiveStatus = data.Report.IsPositive.ToPositiveStatus(),
                Consistency = data.Report.Consistency.ToConsistency(),
                Accord = data.Report.Accord,
                IsCritical = data.Report.IsCritical,
                ImageReaderId = data.Report.ImageReaderId,
                ImageReaderName = data.ImageReader?.Name,
                Flags = data.Report.ToFlags(),
                Status = data.Report.Status,
                FullStatus = data.Report.Status,
                ICDCode = data.Report.ICDCode,
                ACRCode = data.Report.ACRCode
            },
            Study = procedure == null ? null : new StudyArchive
            {
                ImageCount = procedure.ImageAmount,
                IsPrinted = data.Order.IsImagePrinted,
                InsertionTime = data.Order.StudyDate,
                LastImageDateTime = procedure.LastUpdateDateTime,
                LastBuildDateTime = procedure.LastUpdateDateTime,
                StudyDate = data.Order.StudyDate,
                StudyInstanceUIDs = [data.Order.StudyId],
                StorageNode = data.Order.StorageNode,
                FilmCount = procedure.FilmAmount
            },
            Schedule = data.OrderScheduleLog == null ? null : new ScheduleArchive
            {
                ScheduleDoctorCode = data.ScheduleDoctor?.Code,
                ScheduleDoctorName = data.ScheduleDoctor?.Name,
                ScheduleTime = data.OrderScheduleLog.CreateDateTime,
                StartTime = data.Order.ScheduledStartTime ?? default,
                EndTime = data.Order.ScheduledEndTime ?? default
            },
            DiagAssist = !data.Order.RegionAssist ? null : new AssistInfo
            {
                Description = data.Order.RegionAssistComments,
                AssistHospitalCode = data.RegionHospital?.Code,
                AssistHospitalName = data.RegionHospital?.Name,
                LastUpdateTime = data.Order.LastUpdateDateTime,
            }
        };
        archive.ExData = new ExArchiveData(archive);
        return new(archive, data.PdfBase64);
    }

    /// <summary>
    /// 将危重值转化为紧急程度
    /// </summary>
    /// <param name="critical"></param>
    /// <returns></returns>
    public static string ToEmergencyDegree(this Critical critical)
    {
        if (critical == null) return null;
        if (critical.Sort > 1) return "";
        return "";
    }

    /// <summary>
    /// 转化为档案检查项
    /// </summary>
    /// <param name="procedure"></param>
    /// <returns></returns>
    public static ProcedureInfo ToArchiveProcedure(this ProcedureEx procedure)
    {
        var item = new ProcedureInfo
        {
            CheckItemCode = procedure.CheckItem?.Code,
            CheckItemName = procedure.CheckItem?.Name,
            BodyPartCode = procedure.BodyPart?.Code,
            BodyPartName = procedure.BodyPart?.Name,
            CheckFee = procedure.Procedure.CheckFee,
            CheckType = procedure.CheckType?.Name,
            MaterialFee = procedure.Procedure.MaterialFee,
            FilmAmount = procedure.Procedure.FilmAmount,
            FilmSpecName = procedure.Procedure.FilmSpec,
            FilmFee = procedure.Procedure.FilmFee,
            ImageAmount = procedure.Procedure.ImageAmount,
            ExposalAmount = procedure.Procedure.ExposalAmount,
            TimeCount = procedure.CheckItem?.TimeCount ?? 30,
        };
        return item;
    }

    /// <summary>
    /// 将是否阳性转化为阳性状态
    /// </summary>
    /// <param name="isPositive"></param>
    /// <returns></returns>
    public static int? ToPositiveStatus(this bool? isPositive)
    {
        if (isPositive == null) return null;
        return isPositive.Value ? 1 : 0;
    }

    /// <summary>
    /// 将一致性转化为字符串
    /// </summary>
    /// <param name="consistency"></param>
    /// <returns></returns>
    public static string ToConsistency(this int consistency) => consistency switch
    {
        1 => "不符合",
        2 => "基本符合",
        3 => "符合",
        _ => null
    };

    /// <summary>
    /// 将报告标记转化为标记列表
    /// </summary>
    /// <param name="report"></param>
    /// <returns></returns>
    public static string[] ToFlags(this Report report)
    {
        if (report == null) return [];
        return report.NeedFollowUp ? ["NeedFollowUp"] : [];
    }


}
